<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\CustHub\Amqp\Producers\SendRecordProducers;
use App\CustHub\Constants\MsgTypeConstants;
use App\CustHub\Constants\SendConfigConstants;
use App\CustHub\Constants\SmartPushSchemeStatusConstants;
use App\CustHub\Constants\SmartPushSchemeSubStatusConstants;
use App\CustHub\Constants\SmartPushSchemeTaskStatusConstants;
use App\CustHub\Constants\SmartPushSchemeTypeConstants;
use App\CustHub\Dto\SendRecordProducersDto;
use App\CustHub\Helpers\TagReplacer;
use App\CustHub\Mapper\ChSendRecordMapper;
use App\CustHub\Mapper\ChSmartPushSchemeSubTaskMapper;
use App\CustHub\Mapper\ChSmartPushSchemeTaskMapper;
use App\CustHub\Model\ChSmartPushScheme;
use Carbon\Carbon;
use Hyperf\Amqp\Producer;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;

class ChSmartPushSchemeTaskService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected ChSmartPushSchemeSubService $subTaskService;

    #[Inject]
    protected ChSmartPushSchemeSubTaskMapper $subTaskMapper;

    #[Inject]
    protected ChSendRecordMapper $sendRecordMapper;

    public function __construct(ChSmartPushSchemeTaskMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    /**
     * 定时消息处理
     * @return void
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function timedMessageHandler(): void
    {
        $now = Carbon::now()->toDateTimeString();
        $day = Carbon::now()->toDateString();
        $list = ChSmartPushScheme::query()
            ->select(['id','uid','main_uid','cycle_cfg','aud_cfg','content','begin_time','end_time'])
            ->whereIn('status',[SmartPushSchemeStatusConstants::WAITING,SmartPushSchemeStatusConstants::SENDING])
            ->where('begin_time','<=',$now)
            ->where('push_type',SmartPushSchemeTypeConstants::TIMING_REPEAT)
            ->where('is_running',0)
            ->get();

        foreach ($list as $scheme){
            $scheme->is_running = 1;
            $unit = (int)$scheme->cycle_cfg['unit'];
            if($unit == 0){
                $val = [];
            }else{
                $val = $scheme->cycle_cfg['val'];
            }
            $nextSendTime = get_next_send_time($scheme->cycle_cfg['push_time'],(int)$scheme->cycle_cfg['unit'],$val);
            $scheme->begin_time = $nextSendTime;
            $scheme->save();
            if($scheme->end_time < $now || $nextSendTime > $scheme->end_time){
                //任务完成
                $scheme->status = SmartPushSchemeStatusConstants::COMPLETED;
                $scheme->save();
                continue;
            }
            //同一客户是否允许多次推送
            $triggerType = $scheme->cycle_cfg['trigger_type'] ?? 0;
            $isSendUserIds = [];
            if(!$triggerType){
                //不允许的情况
                $isSendUserIds = $this->sendRecordMapper->getUserIdsByTaskId($scheme->id,SendConfigConstants::SMART_PUSH);
            }

            $robotIds = $scheme->robots()->pluck('id')->toArray();
            //获取符合条件的联系人
            $contactList = $this->subTaskService->getQualifiedContactList($robotIds,$scheme->aud_cfg,$isSendUserIds);

            $contactCnt = $contactList->count();
            if($contactCnt == 0){
                $taskStatus = SmartPushSchemeTaskStatusConstants::COMPLETED;
            }else{
                $taskStatus = SmartPushSchemeTaskStatusConstants::SENDING;
            }
            //保存主任务信息
            $taskInfo = [
                'uid' => $scheme->uid,
                'main_uid' => $scheme->main_uid,
                'scheme_id' => $scheme->id,
                'content' => $scheme->content,
                'send_time' => $scheme->begin_time,
                'status' => $taskStatus,
                'contact_cnt' => $contactList->count()
            ];
            $taskId = $this->mapper->save($taskInfo);

            foreach ($robotIds as $robotId){
                $robotContactList = $contactList->filter(function ($item) use ($robotId){
                    return $item->robot_id == $robotId;
                });

                $robotContactListCnt = $robotContactList->count();

                //子任务信息
                $subData = [
                    'scheme_id' => $scheme->id,
                    'task_id' => $taskId,
                    'robot_id' => $robotId,
                    'content' => $scheme->content,
                    'day' => $day,
                    'contact_count' => $robotContactListCnt,
                    'status' => $robotContactListCnt > 0 ? SmartPushSchemeSubStatusConstants::SENDING : SmartPushSchemeSubStatusConstants::COMPLETED,
                ];
                $subTaskId = $this->subTaskMapper->save($subData);
                if($robotContactListCnt > 0){
                    //存储发送目标信息
                    $recordData = [];
                    foreach ($robotContactList as $item){

                        $content = $scheme->content;
                        foreach ($content as $ck=>$contentItem){
                            if($contentItem['msg_type'] == MsgTypeConstants::TEXT){
                                $content[$ck]['content'] = TagReplacer::replaceTags($contentItem['content'],[
                                    'call_name_nickname' => !empty($item->call_name) ? $item->call_name : $item->nickname,
                                ]);
                            }
                        }

                        $recordData[] = [
                            'uid' => $scheme->uid,
                            'main_uid' => $scheme->main_uid,
                            'task_id' => $scheme->id,
                            'sub_task_id' => $subTaskId,
                            'robot_id' => $robotId,
                            'to_id' => $item->user_id,
                            'trigger_time' => time(),
                            'start_time' => 0,//此处设置为不发送
                            'content' => $content,
                            'msg_total_count' => count($scheme->content),
                            'type' => SendConfigConstants::SMART_PUSH,
                        ];
                    }

                    container()->get(Producer::class)->produce(new SendRecordProducers(
                        (new SendRecordProducersDto())
                            ->setMainUid($scheme->main_uid)
                            ->setUid($scheme->uid)
                            ->setTaskId($scheme->id)
                            ->setSubTaskId($subTaskId)
                            ->setType(SendConfigConstants::SMART_PUSH)
                            ->setRecordData($recordData)
                            ->setIsSendNow(true)
                    ));
                }
            }

            if($contactCnt > 0){
                $scheme->contact_count = $scheme->contact_count + $contactCnt;
                $scheme->save();
            }
        }

    }
}